# -*- coding: utf-8 -*-
"""
Adapter Configuration Loader

This module provides utilities to load adapter configurations from YAML files.
"""

import os
import yaml
from pathlib import Path
from typing import Dict, Any, Optional


class AdapterConfigLoader:
    """Load and manage adapter configurations"""
    
    def __init__(self, config_dir: Optional[Path] = None):
        """
        Initialize adapter config loader
        
        Args:
            config_dir: Directory containing adapter YAML files
                       Defaults to the current directory
        """
        if config_dir is None:
            config_dir = Path(__file__).parent
        self.config_dir = Path(config_dir)
        self._configs: Dict[str, Dict[str, Any]] = {}
        
    def load_adapter_config(self, adapter_name: str) -> Dict[str, Any]:
        """
        Load configuration for a specific adapter
        
        Args:
            adapter_name: Name of the adapter (e.g., 'tushare', 'akshare')
            
        Returns:
            Dictionary containing adapter configuration
            
        Raises:
            FileNotFoundError: If adapter config file doesn't exist
            yaml.YAMLError: If config file is invalid YAML
        """
        config_file = self.config_dir / f"{adapter_name}.yaml"
        
        if not config_file.exists():
            raise FileNotFoundError(
                f"Adapter config file not found: {config_file}"
            )
        
        with open(config_file, 'r', encoding='utf-8') as f:
            config = yaml.safe_load(f)
            
        # Override with environment variables if present
        config = self._apply_env_overrides(adapter_name, config)
        
        self._configs[adapter_name] = config
        return config
    
    def _apply_env_overrides(
        self, 
        adapter_name: str, 
        config: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Apply environment variable overrides to config
        
        Environment variables follow the pattern:
        {ADAPTER_NAME}_{SECTION}_{KEY}
        
        Examples:
            TUSHARE_CONNECTION_TOKEN
            INFLUXDB_CONNECTION_URL
            CTP_CONNECTION_BROKER_ID
        """
        prefix = adapter_name.upper()
        
        # Check for common overrides
        env_mappings = {
            # Tushare
            f"{prefix}_TOKEN": ("token",),
            f"{prefix}_TIMEOUT": ("timeout",),
            
            # InfluxDB
            f"{prefix}_URL": ("connection", "url"),
            f"{prefix}_TOKEN": ("connection", "token"),
            f"{prefix}_ORG": ("connection", "org"),
            f"{prefix}_BUCKET": ("connection", "bucket"),
            
            # CTP
            f"{prefix}_BROKER_ID": ("connection", "broker_id"),
            f"{prefix}_USER_ID": ("connection", "user_id"),
            f"{prefix}_PASSWORD": ("connection", "password"),
            f"{prefix}_MD_ADDRESS": ("connection", "md_address"),
            
            # Gateway
            f"{prefix}_GATEWAY_URL": ("connection", "gateway_url"),
            f"{prefix}_API_KEY": ("connection", "api_key"),
            f"{prefix}_API_SECRET": ("connection", "api_secret"),
            
            # Common
            f"{prefix}_ENABLED": ("enabled",),
            f"{prefix}_PRIORITY": ("priority",),
        }
        
        for env_var, keys in env_mappings.items():
            value = os.getenv(env_var)
            if value is not None:
                # Navigate to the nested key and set value
                current = config
                for key in keys[:-1]:
                    if key not in current:
                        current[key] = {}
                    current = current[key]
                
                # Convert value type if needed
                last_key = keys[-1]
                if last_key in current:
                    current_value = current[last_key]
                    if isinstance(current_value, bool):
                        value = value.lower() in ('true', '1', 'yes')
                    elif isinstance(current_value, int):
                        value = int(value)
                    elif isinstance(current_value, float):
                        value = float(value)
                
                current[last_key] = value
        
        return config
    
    def load_all_configs(self) -> Dict[str, Dict[str, Any]]:
        """
        Load all adapter configurations
        
        Returns:
            Dictionary mapping adapter names to their configurations
        """
        yaml_files = self.config_dir.glob("*.yaml")
        
        for yaml_file in yaml_files:
            adapter_name = yaml_file.stem
            try:
                self.load_adapter_config(adapter_name)
            except Exception as e:
                print(f"Warning: Failed to load {adapter_name} config: {e}")
        
        return self._configs
    
    def get_enabled_adapters(self) -> Dict[str, Dict[str, Any]]:
        """
        Get configurations for all enabled adapters
        
        Returns:
            Dictionary of enabled adapter configurations
        """
        if not self._configs:
            self.load_all_configs()
        
        return {
            name: config 
            for name, config in self._configs.items() 
            if config.get("enabled", False)
        }
    
    def get_adapter_priority(self, adapter_name: str) -> int:
        """
        Get priority for an adapter
        
        Args:
            adapter_name: Name of the adapter
            
        Returns:
            Priority value (higher = more priority)
        """
        if adapter_name not in self._configs:
            self.load_adapter_config(adapter_name)
        
        return self._configs[adapter_name].get("priority", 999)
    
    def get_adapters_by_priority(self) -> list[tuple[str, Dict[str, Any]]]:
        """
        Get enabled adapters sorted by priority
        
        Returns:
            List of (adapter_name, config) tuples sorted by priority
        """
        enabled = self.get_enabled_adapters()
        
        return sorted(
            enabled.items(),
            key=lambda x: x[1].get("priority", 999)
        )


# Global loader instance
_loader: Optional[AdapterConfigLoader] = None


def get_adapter_config_loader() -> AdapterConfigLoader:
    """Get global adapter config loader instance"""
    global _loader
    if _loader is None:
        _loader = AdapterConfigLoader()
    return _loader


def load_adapter_config(adapter_name: str) -> Dict[str, Any]:
    """
    Load configuration for a specific adapter
    
    Args:
        adapter_name: Name of the adapter
        
    Returns:
        Adapter configuration dictionary
    """
    loader = get_adapter_config_loader()
    return loader.load_adapter_config(adapter_name)


def get_enabled_adapters() -> Dict[str, Dict[str, Any]]:
    """Get all enabled adapter configurations"""
    loader = get_adapter_config_loader()
    return loader.get_enabled_adapters()


def get_adapters_by_priority() -> list[tuple[str, Dict[str, Any]]]:
    """Get enabled adapters sorted by priority"""
    loader = get_adapter_config_loader()
    return loader.get_adapters_by_priority()


__all__ = [
    "AdapterConfigLoader",
    "get_adapter_config_loader",
    "load_adapter_config",
    "get_enabled_adapters",
    "get_adapters_by_priority",
]

